#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

#define INIT_MAX_SIZE 10

// 创建结构体
typedef struct {
    int *data;
    int MaxSize;
    int length;
} DSqList;

// 初始化
void InitList(DSqList *L, int len) {
    L->data = (int *)malloc(INIT_MAX_SIZE * sizeof(int));
    if (L->data == NULL) {
        printf("内存分配失败！\n");
        exit(1);
    }
    L->length = 0;
    L->MaxSize = INIT_MAX_SIZE;
}

// CRUD
bool addData(DSqList *L, int data) {
    if (L->length >= L->MaxSize) {
        return false;
    }
    L->data[L->length] = data;
    L->length++;
    return true;
}

// e用来接收删除的值
bool deleteData(DSqList *L, int index, int *e) {
    if (index < 1 || index > L->length) {
        return false;
    }
    *e = L->data[index - 1];
    for (int i = index; i < L->length; i++) {
        L->data[i - 1] = L->data[i];
    }
    L->length--;
    return true;
}

bool alterData(DSqList *L, int index, int newData) {
    if (index < 1 || index > L->length) {
        return false;
    }
    L->data[index - 1] = newData;
    return true;
}

void toString(DSqList L) {
    for (int i = 0; i < L.length; i++) {
        printf("%d ", L.data[i]);
    }
    printf("\n");
}

// 插入元素
bool insertData(DSqList *L, int index, int data) {
    if (L->length >= L->MaxSize) {
        return false;
    }
    // 插入位置应在 1 到 L->length + 1 之间
    if (index < 1 || index > L->length + 1) {
        return false;
    }
    for (int i = L->length; i >= index; i--) {
        L->data[i] = L->data[i - 1];
    }
    L->data[index - 1] = data;
    L->length++;
    return true;
}

// 修改最大存储空间
bool increaseMaxSize(DSqList *L, int newMaxSize) {
    // 当新的最大存储空间小于当前已存数据的长度时，不允许修改
    if (newMaxSize < L->length) {
        return false;
    }
    // 保存原数据指针
    int *current = L->data;
    // 分配新的内存空间
    L->data = (int *)malloc(newMaxSize * sizeof(int));
    if (L->data == NULL) {
        printf("内存分配失败！\n");
        return false;
    }
    // 迁移数据
    for (int i = 0; i < L->length; i++) {
        L->data[i] = current[i];
    }
    // 释放原内存空间
    free(current);
    L->MaxSize = newMaxSize;
    return true;
}

void testSequenceList(DSqList *L) {
    char command[20];
    int data, index, newData, deleted, newMaxSize;
    while (1) {
        printf("请输入操作 (add/adds/alter/delete/show/exit/resize): \n");
        scanf("%s", command);

        if (strcmp(command, "add") == 0) {
            printf("请输入要添加的数据: \n");
            scanf("%d", &data);
            if (addData(L, data)) {
                printf("数据添加成功。\n");
            } else {
                printf("顺序表已满，添加失败。\n");
            }
            toString(*L);
        } else if (strcmp(command, "adds") == 0) {
            printf("请输入要批量添加的数据，以空格分隔，输入非数字结束输入: \n");
            while (scanf("%d", &data) == 1) {
                if (!addData(L, data)) {
                    printf("顺序表已满，部分数据未添加成功。\n");
                    break;
                }
            }
            // 清除输入缓冲区中的非数字字符
            while (getchar() != '\n');
            toString(*L);
        } else if (strcmp(command, "alter") == 0) {
            printf("请输入要修改的元素索引 (从 1 开始): \n");
            scanf("%d", &index);
            printf("请输入新的数据: \n");
            scanf("%d", &newData);
            if (alterData(L, index, newData)) {
                printf("数据修改成功。\n");
            } else {
                printf("索引超出范围，修改失败。\n");
            }
            toString(*L);
        } else if (strcmp(command, "delete") == 0) {
            printf("请输入要删除的元素索引 (从 1 开始): \n");
            scanf("%d", &index);
            if (deleteData(L, index, &deleted)) {
                printf("数据删除成功，删除的数据是: %d\n", deleted);
            } else {
                printf("索引超出范围，删除失败。\n");
            }
            toString(*L);
        } else if (strcmp(command, "show") == 0) {
            toString(*L);
        } else if (strcmp(command, "exit") == 0) {
            printf("退出测试。\n");
            break;
        } else if (strcmp(command, "resize") == 0) {
            printf("请输入新的最大容量: \n");
            scanf("%d", &newMaxSize);
            if (increaseMaxSize(L, newMaxSize)) {
                printf("最大容量修改成功。\n");
            } else {
                printf("新的最大容量小于当前数据长度，修改失败。\n");
            }
            toString(*L);
        } else {
            printf("无效的操作，请重新输入。\n");
        }
    }
}

int main() {
    DSqList list;
    InitList(&list, INIT_MAX_SIZE);
    testSequenceList(&list);
    free(list.data);
    return 0;
}